#ifndef GLUT_RENDERER_H
#define GLUT_RENDERER_H

#include "PhysicsLogic.h"
#include "Light.h"
#include "Camera.h"
#include "Textures.h"
#include "SurfaceRenderingData.h"
#include "DevilTexture.h"

#include "WindowsCompatibility/OpenGL.h"

#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#endif //GL_TEXTURE_MAX_ANISOTROPY_EXT

#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#endif //GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT

class Renderer {
public:
	enum MENU_ENTRY {
		MENU_HELP,
		MENU_DEBUG_RENDERING,
		MENU_HUD,
		MENU_CANNON_BALL_CAMERA
	};

protected:
	static int mainWindowHandle;
	static int perfTestWindowHandle;
	static DevilTexture texture[Textures::TEXTURES_COUNT];

	static GLUquadricObj* quadric;

	static bool texturesEnabled;
	static int currentTextureId;

	static int currentMouseX;
	static int currentMouseY;

	static bool anisotropySupported;
	static float maxAnisotropy;

public:
	static int currentTime;
	static SurfaceRenderingData shadowMaterial;

    //for fps calculation
    static int elapsedFpsTime; //will be reset when 1 sec is elapsed
    static int frameCount; //will be reset when 1 sec is elapsed
    static int fps;
	
public:
	static void Init(int argc, char** argv, int width, int height, const char* windowTitle);

	static inline bool IsAnisotropySupported() { return anisotropySupported; }
	static inline float GetMaxAnisotropy() { return maxAnisotropy; }
	static inline int GetMainWindowHandle() { return mainWindowHandle; }
	static inline int GetPerfTestWindowHandle() { return perfTestWindowHandle; }
	static inline void SetPerfTestWindowHandle(int perfTestWindow) { perfTestWindowHandle = perfTestWindow; }
	static inline int GetActiveScreenW() { return glutGet(GLUT_WINDOW_WIDTH); }
	static inline int GetActiveScreenH() { return glutGet(GLUT_WINDOW_HEIGHT); }

	static inline GLUquadricObj* GetQuadric() { return quadric; }

	static void Run();

	static void ClearBuffers();

	static void SetLight(const Light& light);
	static void SetLightState(const Light& light, bool enabled);

	static void Update(const Camera& camera);

	static void SetMaterial(const SurfaceRenderingData& material);
	static void ResetMaterial();

	static void DrawBox(const NxVec3& dim);
	static void DrawSphere(float size);
	static void DrawPoint(float size);
	static void DrawPlane(float size, int iterations, float height);

protected:
	static void ReshapeCallback(int width, int height);
	static void IdleCallback();
	static void RenderCallback();
	static void KeyboardCallback(unsigned char key, int x, int y);
	static void KeyboardSpecialCallback(int key, int x, int y);
	static void MouseClickCallback(int button, int state, int x, int y);
	static void MouseMotionCallback(int x, int y);
	static void MousePassiveMotionCallback(int x, int y);
	static void MenuCallback(int option);

	static void LoadTexture(int index, bool anisotropy);
};

#endif //GLUT_RENDERER_H
